package com.ruoyi.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.websocket.WebSocketServer;
import jakarta.websocket.Session;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;

/**
 * MQTT 客户端配置类，负责建立 MQTT 连接。
 * auth:张沐
 */
@Component
@Slf4j
public class MqttClientConfig {

    public MqttClientConfig() {
        log.info("MqttClientConfig 初始化");
    }

    @Autowired
    private MqttConfiguration mqttConfig;

    private MqttClient mqttClient;

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 初始化 MQTT 客户端并建立连接。
     */
    @PostConstruct
    public void init() {
        try {
            // 创建 MQTT 客户端实例
            mqttClient = new MqttClient(mqttConfig.getHost(), mqttConfig.getClientId(), new MemoryPersistence());
            // 设置回调函数
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    log.info("MQTT 连接丢失: " + cause.getMessage());
                    reconnect();
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    String messageString = new String(message.getPayload());
                    log.info("收到消息 - 主题: " + topic + ", 内容: " + messageString);
                    //将获取到的设备数据转成JSON对象，然后根据UID获取到对应的Session，然后将数据发送给前端
                    JSONObject jsonObject = JSONObject.parseObject(messageString);
                    String uid = jsonObject.getString("UUID");
                    //获取对应的Session
                    Session session = WebSocketServer.getSessionByUid(uid);
                    //判断Session是否为空 ，如果为空证明该设备无人绑定或者绑定该设备的人不在线则不需要进行数据转发
                    if (session != null) {
                        //发送数据给前端
                        JSONObject data = JSONObject.parseObject(messageString);
                        webSocketServer.sendDeviceData(topic, session ,data);
                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    log.info("消息发送完成: " + token.isComplete());
                }
            });

            // 配置连接选项
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
//            connOpts.setUserName(mqttConfig.getUserName());
//            connOpts.setPassword(mqttConfig.getPassWord().toCharArray());
            connOpts.setConnectionTimeout(mqttConfig.getTimeout());
            connOpts.setKeepAliveInterval(mqttConfig.getKeepalive());

            // 建立连接
            mqttClient.connect(connOpts);
            log.info("MQTT 连接成功");

            // 订阅主题
            subscribeTopic();
        } catch (MqttException e) {
            log.info("MQTT 连接失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 重新连接 MQTT 服务器。
     */
    private void reconnect() {
        try {
            if (!mqttClient.isConnected()) {
                mqttClient.connect();
                log.info("MQTT 重新连接成功");
                subscribeTopic();
            }
        } catch (MqttException e) {
            log.info("MQTT 重新连接失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 订阅配置中的主题。
     */
    private void subscribeTopic() {
        try {
            if (mqttConfig.getTopic1() != null && !mqttConfig.getTopic1().isEmpty()) {
                mqttClient.subscribe(mqttConfig.getTopic1(), mqttConfig.getQos());
            }
            if (mqttConfig.getTopic2() != null && !mqttConfig.getTopic2().isEmpty()) {
                mqttClient.subscribe(mqttConfig.getTopic2(), mqttConfig.getQos());
            }
            if (mqttConfig.getTopic3() != null && !mqttConfig.getTopic3().isEmpty()) {
                mqttClient.subscribe(mqttConfig.getTopic3(), mqttConfig.getQos());
            }
            log.info("主题订阅成功");
        } catch (MqttException e) {
            log.info("主题订阅失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 发布消息到指定主题。
     *
     * @param topic 主题名称
     * @param message 消息内容
     */
    public void publishMessage(String topic, String message) {
        try {
            MqttMessage mqttMessage = new MqttMessage(message.getBytes());
            mqttMessage.setQos(mqttConfig.getQos());
            mqttClient.publish(topic, mqttMessage);
        } catch (MqttException e) {
            log.info("消息发布失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 关闭 MQTT 连接。
     */
    public void disconnect() {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.disconnect();
                log.info("MQTT 连接已关闭");
            }
        } catch (MqttException e) {
            log.info("MQTT 连接关闭失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}